/**
 * @date: 2025/3/17
 * @author: 小红
 * @fileName: MicroApp
 * @Description: 无界微服务注册
 */
import { bus, destroyApp, startApp as rawStartApp } from 'wujie';
import { defineComponent, h, onBeforeUnmount, onMounted, ref, watch } from 'vue';
import type { MicroAppConfig } from './index';
import type { Router } from 'vue-router';
import { getLocalConfig } from '@/micro/config';

/**
 * 无界子应用 组件化
 */
const WuJieVue = defineComponent({
	name: 'WuJieVue',
	props: {
		name: { type: String, required: true },
		url: { type: String, required: true },
		loading: { type: Object as () => HTMLElement, default: undefined },
		sync: { type: Boolean, default: undefined },
		prefix: { type: Object, default: undefined },
		alive: { type: Boolean, default: undefined },
		props: { type: Object, default: undefined },
		attrs: { type: Object, default: undefined },
		replace: { type: Function, default: undefined },
		fetch: { type: Function, default: undefined },
		fiber: { type: Boolean, default: undefined },
		degrade: { type: Boolean, default: undefined },
		plugins: { type: Array as () => unknown[], default: () => [] },
		beforeLoad: { type: Function, default: null },
		beforeMount: { type: Function, default: null },
		afterMount: { type: Function, default: null },
		beforeUnmount: { type: Function, default: null },
		afterUnmount: { type: Function, default: null },
		activated: { type: Function, default: null },
		deactivated: { type: Function, default: null },
		loadError: { type: Function, default: null },
	},
	setup(props, { emit, expose }) {
		/**
		 * 无界子应用实例
		 */
		const wujieRef = ref<HTMLElement | null>(null);

		/**
		 * 启动子应用队列
		 */
		const startAppQueue = ref(Promise.resolve());

		/**
		 * 事件触发
		 * @param event
		 * @param args
		 */
		const handleEmit = (event: any, ...args: any) => {
			emit(event, ...args);
		};

		/**
		 * 启动子应用
		 */
		const startApp = async () => {
			try {
				await rawStartApp({
					el: wujieRef.value,
					...props,
				} as any);
			} catch (error) {
				console.error('子应用渲染失败', error);
			}
		};

		/**
		 * 执行启动子应用
		 */
		const execStartApp = () => {
			startAppQueue.value = startAppQueue.value.then(startApp);
		};

		/**
		 * 销毁子应用
		 */
		const destroy = () => {
			destroyApp(props.name);
		};

		/**
		 *  钩子 注册 与 销毁 事件
		 */
		onMounted(() => {
			bus.$onAll(handleEmit);
			execStartApp();
			watch(
				() => props.name + props.url,
				() => execStartApp(),
			);
		});

		/**
		 * 销毁前 移除所有事件
		 */
		onBeforeUnmount(() => {
			bus.$offAll(handleEmit);
		});

		// 暴露 destroy 方法给外部
		expose({
			destroy,
		});

		return () =>
			h('div', {
				class: 'micro-app',
				style: {
					width: '100%',
					height: '100%',
				},
				ref: wujieRef,
			});
	},
});

/**
 * 注册无界子应用和路由
 */
export default function registerWuJieApp(apps: MicroAppConfig[], router: Router) {
	const localConfig = getLocalConfig();

	for (let i = 0; i < apps.length; i++) {
		const conf: any = { ...localConfig, ...apps[i] };

		// rawStartApp(conf)

		router.addRoute('sub', {
			path: conf.name,
			name: conf.name,
			component: h(WuJieVue, conf),
		});
	}
}
